﻿using System;
using System.ServiceModel;
using Rio.Workflow.Runtime;
using Rio.Workflow.WCF.Configuration;
using NetBay.Core.BusinessEntities.Workflow;
using System.Collections.Generic;
using System.Reflection;
using NetBay.Core.BusinessEntities;
using NetBay.Core.Log;
using Rio.Workflow.Runtime.Enums;
using Rio.Flow.Business.Repository;

namespace Rio.Workflow.WCF
{

    /// <summary>
    /// Rio WCF Workflow
    /// </summary>
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
    public class RioWCFWorkflow : IWCFWorkflow
    {
        /// <summary>
        /// Uses to test this instance.
        /// </summary>
        /// <returns></returns>
        public string Test()
        {
            return Assembly.GetExecutingAssembly().FullName + " ready.";
        }

        /// <summary>
        /// Starts the workflow.
        /// </summary>
        /// <param name="context">The creation context.</param>
        /// <returns></returns>
        public bool StartWorkflow(CreationContext context)
        {
            LogManager.Instance().LogInfo("WCF SERVICE CALLED --------------------------");
            LogManager.Instance().LogInfo("---StartWorkflow------context(" + context.ToString() + ")");

            bool result = false;
            try
            {
                //check if there a workflow definition for the parameters
                List<WorkflowDefinition> definitions = WorkflowDefinitionRepository.GetDefinitionsToStart(context.FolderTypeIdentifier, context.StartingCondition);
                foreach (var item in definitions)
                {
                    result |= ServiceManager.Runtime.StartWorkflow(item, context);
                }
                definitions.Clear();
                definitions = null;
            }
            catch (Exception ex)
            {
                LogManager.Instance().LogErrorFormat("WCF StartWorkflow => " + ex.ToString());
            }

            LogManager.Instance().LogInfo(string.Empty);
            LogManager.Instance().LogInfo("---StartWorkflow---------------------------");
            LogManager.Instance().LogInfo("END OF WCF SERVICE CALL ---------------------");
            LogManager.Instance().LogInfo("----------------------------------------------------------------------");

            return result;
        }

        /// <summary>
        /// Starts the workflow2.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        public StartWorkflowResponse StartWorkflow2(CreationContext context)
        {
            LogManager.Instance().LogInfo("WCF SERVICE CALLED --------------------------");
            LogManager.Instance().LogInfo("---StartWorkflow------context(" + context.ToString() + ")");

            StartWorkflowResponse result = new StartWorkflowResponse();
            try
            {
                //check if there a workflow definition for the parameters
                List<WorkflowDefinition> definitions = WorkflowDefinitionRepository.GetDefinitionsToStart(context.FolderTypeIdentifier, context.StartingCondition);
                foreach (var item in definitions)
                {
                    result.StartedInstance.Add(ServiceManager.Runtime.StartWorkflow2(item, context));
                }
                definitions.Clear();
                definitions = null;
            }
            catch (Exception ex)
            {
                LogManager.Instance().LogErrorFormat("WCF StartWorkflow => " + ex.ToString());
            }

            LogManager.Instance().LogInfo(string.Empty);
            LogManager.Instance().LogInfo("---StartWorkflow---------------------------");
            LogManager.Instance().LogInfo("END OF WCF SERVICE CALL ---------------------");
            LogManager.Instance().LogInfo("----------------------------------------------------------------------");

            return result;
        }

        /// <summary>
        /// Determines whether the specified context has workflow.
        /// </summary>
        /// <param name="context">The creation context.</param>
        /// <returns></returns>
        public bool HasWorkflow(CreationContext context)
        {
            LogManager.Instance().LogInfo("WCF SERVICE CALLED --------------------------");
            LogManager.Instance().LogInfo("---HasWorkflow------context(" + context.ToString() + ")");

            bool result = false;
            try
            {
                //check if there a workflow definition for the parameters
                result = WorkflowDefinitionRepository.HasDefinitionsToStart(context.FolderTypeIdentifier, context.StartingCondition);
            }
            catch (Exception ex)
            {
                LogManager.Instance().LogErrorFormat("WCF HasWorkflow => " + ex.ToString());
                throw new Exception("WCF HasWorkflow error " + ex.Message, ex);
            }

            LogManager.Instance().LogInfo(string.Empty);
            LogManager.Instance().LogInfo("---HasWorkflow---------------------------");
            LogManager.Instance().LogInfo("END OF WCF SERVICE CALL ---------------------");
            LogManager.Instance().LogInfo("----------------------------------------------------------------------");

            return result;
        }

        /// <summary>
        /// Requests the chrono.
        /// </summary>
        /// <param name="request">The chrono request.</param>
        /// <returns></returns>
        public ChronoResponse RequestChrono(ChronoRequest request)
        {
            LogManager.Instance().LogInfo("WCF SERVICE CALLED --------------------------");
            LogManager.Instance().LogInfo("---RequestChrono------request(" + request.ToString() + ")");

            Item Result = new Item(0, "");
            ChronoResponse response = new ChronoResponse(Result);
            try
            {
                List<WorkflowDefinition> definitions = WorkflowDefinitionRepository.GetWorkflowDefinitionsByFolderTypeId(request.FolderTypeIdentifier);
                if (definitions != null && definitions.Count > 0)
                    response.Item = ServiceManager.Runtime.RequestChrono(definitions[0], request);
            }
            catch (Exception ex)
            {
                LogManager.Instance().LogErrorFormat("WCF RequestChrono => " + ex.ToString());
            }

            LogManager.Instance().LogInfo(string.Empty);
            LogManager.Instance().LogInfo("---RequestChrono---------------------------");
            LogManager.Instance().LogInfo("END OF WCF SERVICE CALL ---------------------");
            LogManager.Instance().LogInfo("----------------------------------------------------------------------");

            return response;
        }

        /// <summary>
        /// Executes the action.
        /// </summary>
        /// <param name="request">The action request.</param>
        /// <returns></returns>
        public ActionResponse ExecuteAction(ActionRequest request)
        {
            LogManager.Instance().LogInfo("WCF SERVICE CALLED --------------------------");
            LogManager.Instance().LogInfo("---ExecuteAction------ request(" + request.ToString() + " )");

            ActionResponse response = new ActionResponse(ActionResult.Faulted);
            try
            {
                response.Result = ServiceManager.Runtime.ExecuteAction(request);
            }
            catch (Exception ex)
            {
                LogManager.Instance().LogErrorFormat("WCF ExecuteAction => " + ex.ToString());
            }

            LogManager.Instance().LogInfo(string.Empty);
            LogManager.Instance().LogInfo("---ExecuteAction---------------------------");
            LogManager.Instance().LogInfo("END OF WCF SERVICE CALL ---------------------");
            LogManager.Instance().LogInfo("----------------------------------------------------------------------");

            return response;
        }

        /// <summary>
        /// Workflow Instance Opened.
        /// </summary>
        public void WorkflowOpened(long wkfDefinitionId)
        {
            LogManager.Instance().LogInfo("WCF SERVICE CALLED --------------------------");
            LogManager.Instance().LogInfo("---WorkflowOpened------wkfDefinitionId(" + wkfDefinitionId.ToString() + ")");

            try
            {
                if (wkfDefinitionId > 0)
                {
                    WorkflowDefinition workflowDefinition = WorkflowDefinitionRepository.GetWorkflowDefinitionById(wkfDefinitionId);
                    ServiceManager.Runtime.WorkflowOpened(workflowDefinition);
                }
            }
            catch (Exception ex)
            {
                LogManager.Instance().LogErrorFormat("WCF WorkflowOpened => " + ex.ToString());
            }

            LogManager.Instance().LogInfo(string.Empty);
            LogManager.Instance().LogInfo("---WorkflowOpened---------------------------");
            LogManager.Instance().LogInfo("END OF WCF SERVICE CALL ---------------------");
            LogManager.Instance().LogInfo("----------------------------------------------------------------------");
        }
    }
}